﻿using System;
using System.Collections.Generic;
using STeaL.Functional;
using STeaL.Collections.Generic;
using System.Diagnostics;

namespace STeaL.Collections.Generic {
  class Subrange<T> : IEnumerator<T>, IEnumerable<T> {
    public Subrange(IList<T> list, int first, int last) {
      Debug.Assert( first >= 0 && first <= list.Count );
      Debug.Assert( last  >= 0 && last  <= list.Count );
      Debug.Assert( first <= last );
      list_ = list; first_ = first; last_ = last; pos_ = -1;
    }
    
    public T Current { get { return curr_; } }
    object System.Collections.IEnumerator.Current { get { return curr_; } }
    
    public void Dispose() {}

    public bool MoveNext() {
      if ( pos_ < 0 ) pos_ = first_;
      else ++pos_;
      if ( pos_ != last_ ) {
        curr_ = list_[pos_];
        return true;
      }
      return false;
    }

    public void Reset() {
      pos_ = -1;
    }

    public IEnumerator<T> GetEnumerator() { return this; }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this; }
    
    private IList<T> list_;
    private int first_;
    private int last_;
    private int pos_;
    private T   curr_;
  }

}

namespace STeaL.Algorithm {

  public static partial class IListExtensions {
#region subrange
    public static IEnumerable<T> subrange<T>(this IList<T> list, int first, int last) {
      return new Subrange<T>(list, first, last);
    }

    public static IEnumerable<T> subrange<T>(this IList<T> list, Tuple<int,int> range) {
      return new Subrange<T>(list, range.Item1, range.Item2);
    }

#endregion

  }
}
